{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# 分组运算，即分组对象.apply"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  key1  data1  data2\n",
      "0    a      7      5\n",
      "1    b      4      4\n",
      "2    a      8      8\n",
      "3    b      5      8\n",
      "4    a      7      3\n",
      "5    b      3      6\n",
      "6    a      7      5\n",
      "7    a      8      2\n",
      "--------------------------------------------------\n",
      "      mean_data1  mean_data2\n",
      "key1                        \n",
      "a            7.4         4.6\n",
      "b            4.0         6.0\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "np.random.seed(42)\n",
    "#分组后给名称加前缀\n",
    "dict_obj = {'key1' : ['a', 'b', 'a', 'b',\n",
    "                      'a', 'b', 'a', 'a'],\n",
    "            # 'key2' : ['one', 'one', 'two', 'three',\n",
    "            #           'two', 'two', 'one', 'three'],\n",
    "            'data1': np.random.randint(1, 10, 8),\n",
    "            'data2': np.random.randint(1, 10, 8)}\n",
    "df_obj = pd.DataFrame(dict_obj)\n",
    "print(df_obj)\n",
    "print('-'*50)\n",
    "\n",
    "# 按key1分组后，计算data1，data2的统计信息，并添加表头前缀\n",
    "k1_sum = df_obj.groupby('key1').mean().add_prefix('mean_')\n",
    "print(k1_sum)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-04T04:22:24.451453300Z",
     "start_time": "2024-05-04T04:22:24.425383300Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [
    {
     "data": {
      "text/plain": "   mean_data1  mean_data2\n0         7.4         4.6\n1         4.0         6.0\n2         7.4         4.6\n3         4.0         6.0\n4         7.4         4.6\n5         4.0         6.0\n6         7.4         4.6\n7         7.4         4.6",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>mean_data1</th>\n      <th>mean_data2</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>4.0</td>\n      <td>6.0</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>4.0</td>\n      <td>6.0</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n    <tr>\n      <th>5</th>\n      <td>4.0</td>\n      <td>6.0</td>\n    </tr>\n    <tr>\n      <th>6</th>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n    <tr>\n      <th>7</th>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 方法2，使用transform，分组后计算结果和原本的df形状保持一致\n",
    "k1_sum_tf = df_obj.groupby('key1').transform(np.mean).add_prefix('mean_')\n",
    "k1_sum_tf"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-04T04:22:24.493643300Z",
     "start_time": "2024-05-04T04:22:24.454480Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "outputs": [
    {
     "data": {
      "text/plain": "      data1  data2\nkey1              \na       7.4    4.6\nb       4.0    6.0",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>data1</th>\n      <th>data2</th>\n    </tr>\n    <tr>\n      <th>key1</th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>a</th>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n    <tr>\n      <th>b</th>\n      <td>4.0</td>\n      <td>6.0</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_obj.groupby('key1').mean()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-04T04:22:24.494365200Z",
     "start_time": "2024-05-04T04:22:24.470404100Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "outputs": [
    {
     "data": {
      "text/plain": "   data1  data2\n0    7.4    4.6\n1    4.0    6.0\n2    7.4    4.6\n3    4.0    6.0\n4    7.4    4.6\n5    4.0    6.0\n6    7.4    4.6\n7    7.4    4.6",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>data1</th>\n      <th>data2</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>4.0</td>\n      <td>6.0</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>4.0</td>\n      <td>6.0</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n    <tr>\n      <th>5</th>\n      <td>4.0</td>\n      <td>6.0</td>\n    </tr>\n    <tr>\n      <th>6</th>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n    <tr>\n      <th>7</th>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_obj.groupby('key1').transform(np.mean)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-04T04:22:24.504339400Z",
     "start_time": "2024-05-04T04:22:24.484365100Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   diff_mean_data1  diff_mean_data2\n",
      "0             -0.4              0.4\n",
      "1              0.0             -2.0\n",
      "2              0.6              3.4\n",
      "3              1.0              2.0\n",
      "4             -0.4             -1.6\n",
      "5             -1.0              0.0\n",
      "6             -0.4              0.4\n",
      "7              0.6             -2.6\n"
     ]
    }
   ],
   "source": [
    "# a组和b组内，谁比平均分高，谁比平均分低\n",
    "def diff_mean(s):\n",
    "    \"\"\"\n",
    "        返回数据与均值的差值，s传入的是某一个分组\n",
    "    \"\"\"\n",
    "    return s - s.mean()\n",
    "\n",
    "print(df_obj.groupby('key1').transform(diff_mean).add_prefix('diff_mean_'))"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-04T04:22:24.637091400Z",
     "start_time": "2024-05-04T04:22:24.514287Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "outputs": [
    {
     "data": {
      "text/plain": "  key1  data1  data2  mean_data1  mean_data2\n0    a      7      5         7.4         4.6\n1    b      4      4         4.0         6.0\n2    a      8      8         7.4         4.6\n3    b      5      8         4.0         6.0\n4    a      7      3         7.4         4.6\n5    b      3      6         4.0         6.0\n6    a      7      5         7.4         4.6\n7    a      8      2         7.4         4.6",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>key1</th>\n      <th>data1</th>\n      <th>data2</th>\n      <th>mean_data1</th>\n      <th>mean_data2</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>a</td>\n      <td>7</td>\n      <td>5</td>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>b</td>\n      <td>4</td>\n      <td>4</td>\n      <td>4.0</td>\n      <td>6.0</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>a</td>\n      <td>8</td>\n      <td>8</td>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>b</td>\n      <td>5</td>\n      <td>8</td>\n      <td>4.0</td>\n      <td>6.0</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>a</td>\n      <td>7</td>\n      <td>3</td>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n    <tr>\n      <th>5</th>\n      <td>b</td>\n      <td>3</td>\n      <td>6</td>\n      <td>4.0</td>\n      <td>6.0</td>\n    </tr>\n    <tr>\n      <th>6</th>\n      <td>a</td>\n      <td>7</td>\n      <td>5</td>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n    <tr>\n      <th>7</th>\n      <td>a</td>\n      <td>8</td>\n      <td>2</td>\n      <td>7.4</td>\n      <td>4.6</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_obj[k1_sum_tf.columns] = k1_sum_tf\n",
    "df_obj"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-04T04:22:24.687397200Z",
     "start_time": "2024-05-04T04:22:24.543212400Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "# 星际争霸\n",
    "### 根据等级分组，查看 年龄、总时长、APM是否和等级有关"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "outputs": [
    {
     "data": {
      "text/plain": "      LeagueIndex   Age  HoursPerWeek  TotalHours       APM\n0               5  27.0          10.0      3000.0  143.7180\n1               5  23.0          10.0      5000.0  129.2322\n2               4  30.0          10.0       200.0   69.9612\n3               3  19.0          20.0       400.0  107.6016\n4               3  32.0          10.0       500.0  122.8908\n...           ...   ...           ...         ...       ...\n3390            8   NaN           NaN         NaN  259.6296\n3391            8   NaN           NaN         NaN  314.6700\n3392            8   NaN           NaN         NaN  299.4282\n3393            8   NaN           NaN         NaN  375.8664\n3394            8   NaN           NaN         NaN  348.3576\n\n[3395 rows x 5 columns]",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>LeagueIndex</th>\n      <th>Age</th>\n      <th>HoursPerWeek</th>\n      <th>TotalHours</th>\n      <th>APM</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>5</td>\n      <td>27.0</td>\n      <td>10.0</td>\n      <td>3000.0</td>\n      <td>143.7180</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>5</td>\n      <td>23.0</td>\n      <td>10.0</td>\n      <td>5000.0</td>\n      <td>129.2322</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>4</td>\n      <td>30.0</td>\n      <td>10.0</td>\n      <td>200.0</td>\n      <td>69.9612</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>3</td>\n      <td>19.0</td>\n      <td>20.0</td>\n      <td>400.0</td>\n      <td>107.6016</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>3</td>\n      <td>32.0</td>\n      <td>10.0</td>\n      <td>500.0</td>\n      <td>122.8908</td>\n    </tr>\n    <tr>\n      <th>...</th>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n    </tr>\n    <tr>\n      <th>3390</th>\n      <td>8</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>259.6296</td>\n    </tr>\n    <tr>\n      <th>3391</th>\n      <td>8</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>314.6700</td>\n    </tr>\n    <tr>\n      <th>3392</th>\n      <td>8</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>299.4282</td>\n    </tr>\n    <tr>\n      <th>3393</th>\n      <td>8</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>375.8664</td>\n    </tr>\n    <tr>\n      <th>3394</th>\n      <td>8</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>348.3576</td>\n    </tr>\n  </tbody>\n</table>\n<p>3395 rows × 5 columns</p>\n</div>"
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "dataset_path = './starcraft.csv'\n",
    "df_data = pd.read_csv(dataset_path, usecols=['LeagueIndex', 'Age', 'HoursPerWeek','TotalHours', 'APM'])\n",
    "# usecols指定读取的列，不指定则默认读取所有列\n",
    "df_data"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-04T04:22:24.823420600Z",
     "start_time": "2024-05-04T04:22:24.565444400Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "LeagueIndex\n",
      "1    167\n",
      "2    347\n",
      "3    553\n",
      "4    811\n",
      "5    806\n",
      "6    621\n",
      "7     35\n",
      "8     55\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "print(df_data.groupby('LeagueIndex').size())"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-04T04:22:24.824032Z",
     "start_time": "2024-05-04T04:22:24.598710100Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "                  LeagueIndex   Age  HoursPerWeek  TotalHours       APM\n",
      "LeagueIndex                                                            \n",
      "1           2214            1  20.0          12.0       730.0  172.9530\n",
      "            2246            1  27.0           8.0       250.0  141.6282\n",
      "            1753            1  20.0          28.0       100.0  139.6362\n",
      "2           3062            2  20.0           6.0       100.0  179.6250\n",
      "            3229            2  16.0          24.0       110.0  156.7380\n",
      "            1520            2  29.0           6.0       250.0  151.6470\n",
      "3           1557            3  22.0           6.0       200.0  226.6554\n",
      "            484             3  19.0          42.0       450.0  220.0692\n",
      "            2883            3  16.0           8.0       800.0  208.9500\n",
      "4           2688            4  26.0          24.0       990.0  249.0210\n",
      "            1759            4  16.0           6.0        75.0  229.9122\n",
      "            2637            4  23.0          24.0       650.0  227.2272\n",
      "5           3277            5  18.0          16.0       950.0  372.6426\n",
      "            93              5  17.0          36.0       720.0  335.4990\n",
      "            202             5  37.0          14.0       800.0  327.7218\n",
      "6           734             6  16.0          28.0       730.0  389.8314\n",
      "            2746            6  16.0          28.0      4000.0  350.4114\n",
      "            1810            6  21.0          14.0       730.0  323.2506\n",
      "7           3127            7  23.0          42.0      2000.0  298.7952\n",
      "            104             7  21.0          24.0      1000.0  286.4538\n",
      "            1654            7  18.0          98.0       700.0  236.0316\n",
      "8           3393            8   NaN           NaN         NaN  375.8664\n",
      "            3373            8   NaN           NaN         NaN  364.8504\n",
      "            3372            8   NaN           NaN         NaN  355.3518\n",
      "<class 'pandas.core.frame.DataFrame'>\n"
     ]
    }
   ],
   "source": [
    "# apply比agg厉害的地方在于传参数\n",
    "def top_n(df, n=3, column='APM'):   # 默认按照APM排序，并取前三名\n",
    "    \"\"\"\n",
    "        df是某个分组，返回每个分组按 column 的 top n 数据\n",
    "    \"\"\"\n",
    "    return df.sort_values(by=column, ascending=False)[:n]\n",
    "\n",
    "print(df_data.groupby('LeagueIndex').apply(top_n))\n",
    "# print(df_data.groupby('LeagueIndex').apply(top_n, include_groups=False))  # 分组完使用apply，把分组列作为索引"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-04T04:23:02.107606900Z",
     "start_time": "2024-05-04T04:23:02.039799700Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "             LeagueIndex   Age  HoursPerWeek  TotalHours       APM\n",
      "LeagueIndex                                                       \n",
      "1                    1.0  40.0          70.0      1870.0  172.9530\n",
      "2                    2.0  43.0          72.0      2000.0  179.6250\n",
      "3                    3.0  41.0          80.0     10260.0  226.6554\n",
      "4                    4.0  44.0          96.0     18000.0  249.0210\n",
      "5                    5.0  37.0          96.0   1000000.0  372.6426\n",
      "6                    6.0  31.0         168.0     25000.0  389.8314\n",
      "7                    7.0  26.0          98.0     10000.0  298.7952\n",
      "8                    8.0   NaN           NaN         NaN  375.8664\n",
      "----------------------------------------------------------------------------------------------------\n",
      "      LeagueIndex   Age  HoursPerWeek  TotalHours      APM\n",
      "6               1  21.0           8.0       240.0  46.9962\n",
      "36              1  18.0           6.0       230.0  69.5076\n",
      "106             1  33.0           4.0       120.0  68.6598\n",
      "167             1  22.0          20.0       315.0  54.0792\n",
      "187             1  19.0          16.0       730.0  60.4956\n",
      "...           ...   ...           ...         ...      ...\n",
      "3208            1  24.0          24.0        40.0  37.2630\n",
      "3237            1  28.0           2.0        30.0  98.7384\n",
      "3291            1  20.0          12.0       100.0  51.6534\n",
      "3298            1  37.0          12.0       300.0  22.0596\n",
      "3316            1  25.0           4.0       200.0  74.3232\n",
      "\n",
      "[167 rows x 5 columns]\n",
      "LeagueIndex        1.000\n",
      "Age               40.000\n",
      "HoursPerWeek      70.000\n",
      "TotalHours      1870.000\n",
      "APM              172.953\n",
      "dtype: float64\n",
      "----------------------------------------------------------------------------------------------------\n",
      "LeagueIndex           8.0000\n",
      "Age                  44.0000\n",
      "HoursPerWeek        168.0000\n",
      "TotalHours      1000000.0000\n",
      "APM                 389.8314\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "print(df_data.groupby('LeagueIndex').apply(lambda x:x.max()))\n",
    "print(\"-\"*100)\n",
    "\n",
    "# 第一组df进行max，和分组对象进行max，结果不一样。但格式一样\n",
    "for i in df_data.groupby('LeagueIndex'):\n",
    "    print(i[1])\n",
    "    print(i[1].apply(lambda x:x.max()))\n",
    "    break\n",
    "print(\"-\"*100)\n",
    "\n",
    "print(df_data.apply(lambda x:x.max()))"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-05-04T04:50:06.596151Z",
     "start_time": "2024-05-04T04:50:06.542296200Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "outputs": [
    {
     "data": {
      "text/plain": "                  LeagueIndex   Age  HoursPerWeek  TotalHours       APM\nLeagueIndex                                                            \n1           3146            1  40.0          12.0       150.0   38.5590\n            3040            1  39.0          10.0       500.0   29.8764\n2           920             2  43.0          10.0       730.0   86.0586\n            2437            2  41.0           4.0       200.0   54.2166\n3           1258            3  41.0          14.0       800.0   77.6472\n            2972            3  40.0          10.0       500.0   60.5970\n4           1696            4  44.0           6.0       500.0   89.5266\n            1729            4  39.0           8.0       500.0   86.7246\n5           202             5  37.0          14.0       800.0  327.7218\n            2745            5  37.0          18.0      1000.0  123.4098\n6           3069            6  31.0           8.0       800.0  133.1790\n            2706            6  31.0           8.0       700.0   66.9918\n7           2813            7  26.0          36.0      1300.0  188.5512\n            1992            7  26.0          24.0      1000.0  219.6690\n8           3340            8   NaN           NaN         NaN  189.7404\n            3341            8   NaN           NaN         NaN  287.8128",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th></th>\n      <th>LeagueIndex</th>\n      <th>Age</th>\n      <th>HoursPerWeek</th>\n      <th>TotalHours</th>\n      <th>APM</th>\n    </tr>\n    <tr>\n      <th>LeagueIndex</th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n      <th></th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">1</th>\n      <th>3146</th>\n      <td>1</td>\n      <td>40.0</td>\n      <td>12.0</td>\n      <td>150.0</td>\n      <td>38.5590</td>\n    </tr>\n    <tr>\n      <th>3040</th>\n      <td>1</td>\n      <td>39.0</td>\n      <td>10.0</td>\n      <td>500.0</td>\n      <td>29.8764</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">2</th>\n      <th>920</th>\n      <td>2</td>\n      <td>43.0</td>\n      <td>10.0</td>\n      <td>730.0</td>\n      <td>86.0586</td>\n    </tr>\n    <tr>\n      <th>2437</th>\n      <td>2</td>\n      <td>41.0</td>\n      <td>4.0</td>\n      <td>200.0</td>\n      <td>54.2166</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">3</th>\n      <th>1258</th>\n      <td>3</td>\n      <td>41.0</td>\n      <td>14.0</td>\n      <td>800.0</td>\n      <td>77.6472</td>\n    </tr>\n    <tr>\n      <th>2972</th>\n      <td>3</td>\n      <td>40.0</td>\n      <td>10.0</td>\n      <td>500.0</td>\n      <td>60.5970</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">4</th>\n      <th>1696</th>\n      <td>4</td>\n      <td>44.0</td>\n      <td>6.0</td>\n      <td>500.0</td>\n      <td>89.5266</td>\n    </tr>\n    <tr>\n      <th>1729</th>\n      <td>4</td>\n      <td>39.0</td>\n      <td>8.0</td>\n      <td>500.0</td>\n      <td>86.7246</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">5</th>\n      <th>202</th>\n      <td>5</td>\n      <td>37.0</td>\n      <td>14.0</td>\n      <td>800.0</td>\n      <td>327.7218</td>\n    </tr>\n    <tr>\n      <th>2745</th>\n      <td>5</td>\n      <td>37.0</td>\n      <td>18.0</td>\n      <td>1000.0</td>\n      <td>123.4098</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">6</th>\n      <th>3069</th>\n      <td>6</td>\n      <td>31.0</td>\n      <td>8.0</td>\n      <td>800.0</td>\n      <td>133.1790</td>\n    </tr>\n    <tr>\n      <th>2706</th>\n      <td>6</td>\n      <td>31.0</td>\n      <td>8.0</td>\n      <td>700.0</td>\n      <td>66.9918</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">7</th>\n      <th>2813</th>\n      <td>7</td>\n      <td>26.0</td>\n      <td>36.0</td>\n      <td>1300.0</td>\n      <td>188.5512</td>\n    </tr>\n    <tr>\n      <th>1992</th>\n      <td>7</td>\n      <td>26.0</td>\n      <td>24.0</td>\n      <td>1000.0</td>\n      <td>219.6690</td>\n    </tr>\n    <tr>\n      <th rowspan=\"2\" valign=\"top\">8</th>\n      <th>3340</th>\n      <td>8</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>189.7404</td>\n    </tr>\n    <tr>\n      <th>3341</th>\n      <td>8</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>287.8128</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# apply函数接收的参数会传入自定义的函数中\n",
    "m=df_data.groupby('LeagueIndex').apply(top_n, n=2, column='Age')\n",
    "m"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-02T14:27:34.273276600Z",
     "start_time": "2024-05-02T14:27:34.211508700Z"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "outputs": [
    {
     "data": {
      "text/plain": "      LeagueIndex   Age  HoursPerWeek  TotalHours       APM\n2214            1  20.0          12.0       730.0  172.9530\n2246            1  27.0           8.0       250.0  141.6282\n1753            1  20.0          28.0       100.0  139.6362\n3062            2  20.0           6.0       100.0  179.6250\n3229            2  16.0          24.0       110.0  156.7380\n1520            2  29.0           6.0       250.0  151.6470\n1557            3  22.0           6.0       200.0  226.6554\n484             3  19.0          42.0       450.0  220.0692\n2883            3  16.0           8.0       800.0  208.9500\n2688            4  26.0          24.0       990.0  249.0210\n1759            4  16.0           6.0        75.0  229.9122\n2637            4  23.0          24.0       650.0  227.2272\n3277            5  18.0          16.0       950.0  372.6426\n93              5  17.0          36.0       720.0  335.4990\n202             5  37.0          14.0       800.0  327.7218\n734             6  16.0          28.0       730.0  389.8314\n2746            6  16.0          28.0      4000.0  350.4114\n1810            6  21.0          14.0       730.0  323.2506\n3127            7  23.0          42.0      2000.0  298.7952\n104             7  21.0          24.0      1000.0  286.4538\n1654            7  18.0          98.0       700.0  236.0316\n3393            8   NaN           NaN         NaN  375.8664\n3373            8   NaN           NaN         NaN  364.8504\n3372            8   NaN           NaN         NaN  355.3518",
      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>LeagueIndex</th>\n      <th>Age</th>\n      <th>HoursPerWeek</th>\n      <th>TotalHours</th>\n      <th>APM</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>2214</th>\n      <td>1</td>\n      <td>20.0</td>\n      <td>12.0</td>\n      <td>730.0</td>\n      <td>172.9530</td>\n    </tr>\n    <tr>\n      <th>2246</th>\n      <td>1</td>\n      <td>27.0</td>\n      <td>8.0</td>\n      <td>250.0</td>\n      <td>141.6282</td>\n    </tr>\n    <tr>\n      <th>1753</th>\n      <td>1</td>\n      <td>20.0</td>\n      <td>28.0</td>\n      <td>100.0</td>\n      <td>139.6362</td>\n    </tr>\n    <tr>\n      <th>3062</th>\n      <td>2</td>\n      <td>20.0</td>\n      <td>6.0</td>\n      <td>100.0</td>\n      <td>179.6250</td>\n    </tr>\n    <tr>\n      <th>3229</th>\n      <td>2</td>\n      <td>16.0</td>\n      <td>24.0</td>\n      <td>110.0</td>\n      <td>156.7380</td>\n    </tr>\n    <tr>\n      <th>1520</th>\n      <td>2</td>\n      <td>29.0</td>\n      <td>6.0</td>\n      <td>250.0</td>\n      <td>151.6470</td>\n    </tr>\n    <tr>\n      <th>1557</th>\n      <td>3</td>\n      <td>22.0</td>\n      <td>6.0</td>\n      <td>200.0</td>\n      <td>226.6554</td>\n    </tr>\n    <tr>\n      <th>484</th>\n      <td>3</td>\n      <td>19.0</td>\n      <td>42.0</td>\n      <td>450.0</td>\n      <td>220.0692</td>\n    </tr>\n    <tr>\n      <th>2883</th>\n      <td>3</td>\n      <td>16.0</td>\n      <td>8.0</td>\n      <td>800.0</td>\n      <td>208.9500</td>\n    </tr>\n    <tr>\n      <th>2688</th>\n      <td>4</td>\n      <td>26.0</td>\n      <td>24.0</td>\n      <td>990.0</td>\n      <td>249.0210</td>\n    </tr>\n    <tr>\n      <th>1759</th>\n      <td>4</td>\n      <td>16.0</td>\n      <td>6.0</td>\n      <td>75.0</td>\n      <td>229.9122</td>\n    </tr>\n    <tr>\n      <th>2637</th>\n      <td>4</td>\n      <td>23.0</td>\n      <td>24.0</td>\n      <td>650.0</td>\n      <td>227.2272</td>\n    </tr>\n    <tr>\n      <th>3277</th>\n      <td>5</td>\n      <td>18.0</td>\n      <td>16.0</td>\n      <td>950.0</td>\n      <td>372.6426</td>\n    </tr>\n    <tr>\n      <th>93</th>\n      <td>5</td>\n      <td>17.0</td>\n      <td>36.0</td>\n      <td>720.0</td>\n      <td>335.4990</td>\n    </tr>\n    <tr>\n      <th>202</th>\n      <td>5</td>\n      <td>37.0</td>\n      <td>14.0</td>\n      <td>800.0</td>\n      <td>327.7218</td>\n    </tr>\n    <tr>\n      <th>734</th>\n      <td>6</td>\n      <td>16.0</td>\n      <td>28.0</td>\n      <td>730.0</td>\n      <td>389.8314</td>\n    </tr>\n    <tr>\n      <th>2746</th>\n      <td>6</td>\n      <td>16.0</td>\n      <td>28.0</td>\n      <td>4000.0</td>\n      <td>350.4114</td>\n    </tr>\n    <tr>\n      <th>1810</th>\n      <td>6</td>\n      <td>21.0</td>\n      <td>14.0</td>\n      <td>730.0</td>\n      <td>323.2506</td>\n    </tr>\n    <tr>\n      <th>3127</th>\n      <td>7</td>\n      <td>23.0</td>\n      <td>42.0</td>\n      <td>2000.0</td>\n      <td>298.7952</td>\n    </tr>\n    <tr>\n      <th>104</th>\n      <td>7</td>\n      <td>21.0</td>\n      <td>24.0</td>\n      <td>1000.0</td>\n      <td>286.4538</td>\n    </tr>\n    <tr>\n      <th>1654</th>\n      <td>7</td>\n      <td>18.0</td>\n      <td>98.0</td>\n      <td>700.0</td>\n      <td>236.0316</td>\n    </tr>\n    <tr>\n      <th>3393</th>\n      <td>8</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>375.8664</td>\n    </tr>\n    <tr>\n      <th>3373</th>\n      <td>8</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>364.8504</td>\n    </tr>\n    <tr>\n      <th>3372</th>\n      <td>8</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>NaN</td>\n      <td>355.3518</td>\n    </tr>\n  </tbody>\n</table>\n</div>"
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# group_keys为False后，被groupby的列不会变为行索引\n",
    "n=df_data.groupby('LeagueIndex', group_keys=False).apply(top_n)\n",
    "n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    },
    "ExecuteTime": {
     "end_time": "2024-05-02T15:05:33.243690600Z",
     "start_time": "2024-05-02T15:05:33.191824300Z"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [],
   "metadata": {
    "collapsed": false
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
